package com.snail.common.dyd.config;


import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.creator.druid.DruidDataSourceCreator;
import com.snail.common.dyd.*;
import com.snail.common.dyd.hepler.DataSourceHelper;
import com.snail.common.dyd.impl.DefaultDataBaseOperatorProvider;
import com.snail.common.dyd.impl.DefaultDataSourceSwitcher;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

import javax.sql.DataSource;

@Configuration
@DependsOn
@ConditionalOnBean({DynamicDataBase.class, DruidDataSourceCreator.class, DataSource.class, DataSourceInfoProvider.class})
public class DynamicDataBaseConfigration {

    @ConditionalOnBean({DruidDataSourceCreator.class, DataSource.class})
    @Bean
    public DataSourceHelper dataSourceHolder(DruidDataSourceCreator dataSourceCreator,
                                             DataSource dataSource) {
        if(dataSource instanceof DynamicRoutingDataSource){
            DynamicRoutingDataSource dynamicRoutingDataSource = (DynamicRoutingDataSource) dataSource;
            return new DataSourceHelper(dataSourceCreator, dynamicRoutingDataSource);
        }
        return null;
    }

    @Bean
    @ConditionalOnMissingBean(DataBaseOperatorProvider.class)
    public DataBaseOperatorProvider dataBaseOperatorProvider(ApplicationContext context) {
        return new DefaultDataBaseOperatorProvider(context);
    }

    @Bean
    @ConditionalOnMissingBean(DataSourceSwitcher.class)
    public DataSourceSwitcher dataSourceSwitcher(DataSourceHelper dataSourceHelper) {
        return new DefaultDataSourceSwitcher(dataSourceHelper);
    }

    @Bean
    @ConditionalOnBean({DataBaseOperatorProvider.class, DataSourceInfoProvider.class})
    public AspectDynamicDataBaseProcessor dynamicDataBaseProcessor(
            DataBaseOperatorProvider dataBaseOperatorProvider,
            DataSourceInfoProvider dataSourceInfoProvider,
            DataSourceSwitcher dataSourceSwitcher
    ) {
        return new AspectDynamicDataBaseProcessor(dataBaseOperatorProvider, dataSourceSwitcher, dataSourceInfoProvider);
    }


    @Bean
    public DynamicDatabaseProcessAspect dynamicDataBaseProcessAspect(AspectDynamicDataBaseProcessor dynamicDataBaseProcessor) {
        return new DynamicDatabaseProcessAspect(dynamicDataBaseProcessor);
    }

}
